home *** CD-ROM | disk | FTP | other *** search
- #define LIBQBUILD_CORE
- #include "../include/libqbuild.h"
-
- int headclipnode; // 4
- int firstface; // 4
-
- /* changed by niels */
- int *planemapping;
-
- //===========================================================================
-
- /*
- * ==================
- * FindFinalPlane
- *
- * Used to find plane index numbers for clip nodes read from child processes
- * ==================
- */
- int FindFinalPlane(__memBase, struct dplane_t * p)
- {
- int i;
- struct dplane_t *dplane;
-
- for (i = 0, dplane = bspMem->dplanes; i < bspMem->numplanes; i++, dplane++) {
- if (p->type != dplane->type)
- continue;
- if (p->dist != dplane->dist)
- continue;
- if (p->normal[0] != dplane->normal[0])
- continue;
- if (p->normal[1] != dplane->normal[1])
- continue;
- if (p->normal[2] != dplane->normal[2])
- continue;
- return i;
- }
-
- //
- // new plane
- //
- if (bspMem->numplanes == bspMem->max_numplanes)
- ExpandClusters(bspMem, LUMP_PLANES);
- dplane = &bspMem->dplanes[bspMem->numplanes];
- *dplane = *p;
- bspMem->numplanes++;
-
- return bspMem->numplanes - 1;
- }
-
- void WriteNodePlanes_r(__memBase, register struct node * node)
- {
- struct plane *plane;
- struct dplane_t *dplane;
-
- if (node->planenum == -1)
- return;
- if (planemapping[node->planenum] == -1) { // a new plane
-
- planemapping[node->planenum] = bspMem->numplanes;
-
- if (bspMem->numplanes == bspMem->max_numplanes)
- ExpandClusters(bspMem, LUMP_PLANES);
- #ifdef EXHAUSIVE_CHECK
- if(node->planenum >= bspMem->numbrushplanes || node->planenum < 0)
- Error("looking for nonexisting plane %d\n", node->planenum);
- #endif
- plane = &bspMem->brushplanes[node->planenum];
- dplane = &bspMem->dplanes[bspMem->numplanes];
- dplane->normal[0] = plane->normal[0];
- dplane->normal[1] = plane->normal[1];
- dplane->normal[2] = plane->normal[2];
- dplane->dist = plane->dist;
- dplane->type = plane->type;
-
- bspMem->numplanes++;
- }
-
- node->outputplanenum = planemapping[node->planenum];
-
- WriteNodePlanes_r(bspMem, node->children[0]);
- WriteNodePlanes_r(bspMem, node->children[1]);
- }
-
- /*
- * ==================
- * WriteNodePlanes
- *
- * ==================
- */
- void WriteNodePlanes(__memBase, struct node * nodes)
- {
- /* added by niels -> probably not numbrushplanes */
- if(!(planemapping = (int *)tmalloc(sizeof(int) * bspMem->numbrushplanes)))
- Error("WriteNodePlanes: failed to allocate planemapping\n");
- memset(planemapping, -1, sizeof(int) * bspMem->numbrushplanes);
- WriteNodePlanes_r(bspMem, nodes);
- /* added by niels */
- tfree(planemapping);
- }
-
- //===========================================================================
-
- /*
- * ==================
- * WriteClipNodes_r
- *
- * ==================
- */
- int WriteClipNodes_r(__memBase, register struct node * node)
- {
- int c;
- short int i;
- struct dclipnode_t *cn;
- int num;
-
- // FIXME: tfree more stuff?
- if (node->planenum == -1) {
- num = node->contents;
- tfree(node);
- return num;
- }
-
- if (bspMem->numclipnodes == bspMem->max_numclipnodes)
- ExpandClusters(bspMem, LUMP_CLIPNODES);
- // emit a clipnode
- c = bspMem->numclipnodes;
- cn = &bspMem->dclipnodes[c];
- bspMem->numclipnodes++;
-
- cn->planenum = node->outputplanenum;
- for (i = 0; i < 2; i++)
- cn->children[i] = WriteClipNodes_r(bspMem, node->children[i]);
-
- tfree(node);
- return c;
- }
-
- /*
- * ==================
- * WriteClipNodes
- *
- * Called after the clipping hull is completed. Generates a disk format
- * representation and frees the original memory.
- * ==================
- */
- void WriteClipNodes(__memBase, struct node * nodes)
- {
- headclipnode = bspMem->numclipnodes;
- WriteClipNodes_r(bspMem, nodes);
- }
-
- //===========================================================================
-
- /*
- * ==================
- * WriteLeaf
- * ==================
- */
- void WriteLeaf(__memBase, register struct node * node)
- {
- struct visfacet **fp, *f;
- struct dleaf_t *leaf_p;
-
- // emit a leaf
- if (bspMem->numleafs == bspMem->max_numleafs)
- ExpandClusters(bspMem, LUMP_LEAFS);
- leaf_p = &bspMem->dleafs[bspMem->numleafs];
- bspMem->numleafs++;
-
- leaf_p->contents = node->contents;
-
- //
- // write bounding box info
- //
- VectorCopy(node->mins, leaf_p->mins);
- VectorCopy(node->maxs, leaf_p->maxs);
-
- leaf_p->visofs = -1; // no vis info yet
-
- //
- // write the marksurfaces
- //
- leaf_p->firstmarksurface = bspMem->nummarksurfaces;
-
- for (fp = node->markfaces; *fp; fp++) {
- // emit a marksurface
- f = *fp;
- do {
- if (bspMem->nummarksurfaces == bspMem->max_nummarksurfaces)
- ExpandClusters(bspMem, LUMP_MARKSURFACES);
- bspMem->dmarksurfaces[bspMem->nummarksurfaces] = f->outputnumber;
- bspMem->nummarksurfaces++;
- f = f->original; // grab tjunction split faces
- } while (f);
- }
-
- leaf_p->nummarksurfaces = bspMem->nummarksurfaces - leaf_p->firstmarksurface;
- }
-
- /*
- * ==================
- * WriteDrawNodes_r
- * ==================
- */
- void WriteDrawNodes_r(__memBase, register struct node * node)
- {
- struct dnode_t *n;
- short int i;
-
- // emit a node
- if (bspMem->numnodes == bspMem->max_numnodes)
- ExpandClusters(bspMem, LUMP_NODES);
- n = &bspMem->dnodes[bspMem->numnodes];
- bspMem->numnodes++;
-
- VectorCopy(node->mins, n->mins);
- VectorCopy(node->maxs, n->maxs);
-
- n->planenum = node->outputplanenum;
- n->firstface = node->firstface;
- n->numfaces = node->numfaces;
-
- //
- // recursively output the other nodes
- //
-
- for (i = 0; i < 2; i++) {
- if (node->children[i]->planenum == -1) {
- if (node->children[i]->contents == CONTENTS_SOLID)
- n->children[i] = -1;
- else {
- n->children[i] = -(bspMem->numleafs + 1);
- WriteLeaf(bspMem, node->children[i]);
- }
- }
- else {
- n->children[i] = bspMem->numnodes;
- WriteDrawNodes_r(bspMem, node->children[i]);
- }
- }
- }
-
- /*
- * ==================
- * WriteDrawNodes
- * ==================
- */
- void WriteDrawNodes(__memBase, struct node * headnode)
- {
- short int i;
- int start;
- struct dmodel_t *bm;
-
- #if 0
- if (headnode->contents < 0)
- Error("FinishBSPModel: empty model");
- #endif
-
- // emit a model
- if (bspMem->nummodels == bspMem->max_nummodels)
- ExpandClusters(bspMem, LUMP_MODELS);
- bm = &bspMem->dmodels[bspMem->nummodels];
- bspMem->nummodels++;
-
- bm->headnode[0] = bspMem->numnodes;
- bm->firstface = firstface;
- bm->numfaces = bspMem->numfaces - firstface;
- firstface = bspMem->numfaces;
-
- start = bspMem->numleafs;
-
- if (headnode->contents < 0)
- WriteLeaf(bspMem, headnode);
- else
- WriteDrawNodes_r(bspMem, headnode);
- bm->visleafs = bspMem->numleafs - start;
-
- for (i = 0; i < 3; i++) {
- bm->mins[i] = headnode->mins[i] + SIDESPACE + 1; // remove the padding
- bm->maxs[i] = headnode->maxs[i] - SIDESPACE - 1;
- }
- // FIXME: are all the children decendant of padded nodes?
- }
-
- /*
- * ==================
- * BumpModel
- *
- * Used by the clipping hull processes that only need to store headclipnode
- * ==================
- */
- void BumpModel(__memBase, int hullnum)
- {
- struct dmodel_t *bm;
-
- // emit a model
- if (bspMem->nummodels == bspMem->max_nummodels)
- ExpandClusters(bspMem, LUMP_MODELS);
- bm = &bspMem->dmodels[bspMem->nummodels];
- bspMem->nummodels++;
-
- bm->headnode[hullnum] = headclipnode;
- }
-
- //=============================================================================
-
- #define MAX_MULTIPLE 32
-
- /*
- * ==================
- * WriteMiptex
- * ==================
- */
- void WriteMiptex(__memBase)
- {
- if(!(bspMem->bspOptions & QBSP_NOTEXTURES)) {
- struct wadheader Header[MAX_MULTIPLE + 1];
- struct wadentry *allEntries[MAX_MULTIPLE + 1];
- char *wadPath[MAX_MULTIPLE + 1];
- FILE *wadFile[MAX_MULTIPLE + 1];
- int wadAvail = 0;
-
- char *dirPath[MAX_MULTIPLE + 1];
- DIR *dirDir[MAX_MULTIPLE + 1];
- int dirAvail = 0;
-
- /* TODO: multiple wadFiles */
- wadPath[0] = ValueForKey(&bspMem->mapentities[0], "_wad");
- if (!wadPath[0] || !wadPath[0][0])
- wadPath[0] = ValueForKey(&bspMem->mapentities[0], "wad");
- if (!wadPath[0] || !wadPath[0][0])
- wadPath[0] = getenv("QUAKE_WADFILE");
-
- for(wadAvail = 0; wadAvail < MAX_MULTIPLE;) {
- char *hit;
-
- if((hit = (char *)index(wadPath[wadAvail], ';'))) { // cut off next entry
- *hit = ' ';
- while((hit[-1] == ' ') || (hit[-1] == '\t')) // delete whitespace
- hit--;
- *hit++ = '\0';
- while((*hit == ' ') || (*hit == '\t')) // delete whitespace
- hit++;
- }
- #ifdef DEBUG
- printf("wadPath %2d: \"%s\"\n", wadAvail, wadPath[wadAvail]);
- #endif
-
- if((wadPath[wadAvail][0]) && (wadFile[wadAvail] = fopen(wadPath[wadAvail], READ_BINARY))) {
- if(CheckWAD2(wadFile[wadAvail], &Header[wadAvail], FALSE) == TRUE) {
- FindWAD2(wadFile[wadAvail], 0, &Header[wadAvail], &allEntries[wadAvail], 0);
- wadAvail++;
- }
- else {
- fclose(wadFile[wadAvail]);
- eprintf("file \"%s\" not a wad\n", wadPath[wadAvail]);
- }
- }
- else
- eprintf("wad \"%s\" not found\n", wadPath[wadAvail]);
-
- if(!hit) // break if nothing more found
- break;
- else
- wadPath[wadAvail] = hit; // register next entry
- }
-
- /* TODO: multiple dirDirs */
- dirPath[0] = ValueForKey(&bspMem->mapentities[0], "_dir");
- if (!dirPath[0] || !dirPath[0][0])
- dirPath[0] = ValueForKey(&bspMem->mapentities[0], "dir");
- if (!dirPath[0] || !dirPath[0][0])
- dirPath[0] = getenv("QUAKE_WADDIR");
- if (!dirPath[0] || !dirPath[0][0])
- dirPath[0] = "\0";
-
- for(dirAvail = 0; dirAvail < MAX_MULTIPLE;) {
- char *hit;
-
- if((hit = (char *)index(dirPath[dirAvail], ';'))) { // cut off next entry
- *hit = ' ';
- while((hit[-1] == ' ') || (hit[-1] == '\t')) // delete whitespace
- hit--;
- *hit++ = '\0';
- while((*hit == ' ') || (*hit == '\t')) // delete whitespace
- hit++;
- }
- #ifdef DEBUG
- printf("dirPath %2d: \"%s\"\n", dirAvail, dirPath[dirAvail]);
- #endif
-
- if((dirDir[dirAvail] = opendir(dirPath[dirAvail])))
- dirAvail++; // skip unavailable entries
- else
- eprintf("dir \"%s\" is not a dir, or does not exists\n", dirPath[dirAvail]);
-
- if(!hit) // break if nothing more found
- break;
- else
- dirPath[dirAvail] = hit; // register next entry
- }
- #ifdef DEBUG
- printf("wads %2d, dirs %2d\n", wadAvail, dirAvail);
- #endif
-
- if(wadAvail || dirAvail) {
- int i;
- unsigned char *mipFlow;
- struct dmiptexlump_t *mipBlock;
- int texstrings = bspMem->nummaptexstrings;
-
- mipBlock = (struct dmiptexlump_t *) bspMem->dtexdata;
- mipFlow = (unsigned char *) & mipBlock->dataofs[bspMem->nummaptexstrings];
- mipBlock->nummiptex = bspMem->nummaptexstrings;
- bspMem->texdatasize = mipFlow - bspMem->dtexdata;
-
- for (i = 0; i < texstrings; i++) {
- struct rawdata *inPut;
-
- void GetInput(char *inName) {
- int j;
- struct wadentry *Entry;
-
- inPut = 0;
-
- /* first search in wadFiles */
- for(j = 0; j < wadAvail; j++)
- if((Entry = SearchWAD2(inName, &Header[j], allEntries[j], TYPE_MIPMAP)))
- inPut = GetWAD2Raw(wadFile[j], Entry);
-
- /* if nothing found, search in dirDirs */
- for(j = 0; (j < dirAvail) && !(inPut); j++) {
- struct dirent *dirEnt = 0;
-
- while((dirEnt = readdir(dirDir[j]))) {
- #ifdef DEBUG
- printf("dirname: %s wadname: %s\n", dirEnt->d_name, inName);
- #endif
- if(!strncasecmp(dirEnt->d_name, inName, strlen(inName))) // metal1 matches metal10*
- if(dirEnt->d_name[strlen(inName)] == '.') // metal1 matches metal1.*
- break;
- }
-
- if(dirEnt) {
- char *fileExt = GetExt(dirEnt->d_name);
- FILE *inFile;
- struct palpic *inPic = 0;
- char *fileName;
-
- if((fileName = (char *)tmalloc(NAMELEN_PATH + 1))) {
- strncpy(fileName, dirPath[j], NAMELEN_PATH);
- strncat(fileName, "/", NAMELEN_PATH);
- strncat(fileName, dirEnt->d_name, NAMELEN_PATH);
-
- if((inFile = fopen(fileName, READ_BINARY))) {
- if(!strcmp(fileExt, "mip"))
- inPut = GetRaw(inFile, inName, 0);
- else if(!strcmp(fileExt, "lmp"))
- inPic = GetLMP(inFile, inName);
- else {
- short int alignX = 16, alignY = 16;
-
- if (fileName[0] == WARP_MIPMAP)
- alignX = alignY = WARP_X;
- else if (!strncasecmp(fileName, SKY_MIPMAP, 3)) {
- alignX = -(SKY_X);
- alignY = -(SKY_Y);
- }
- inPic = GetImage(inFile, inName, alignX, alignY);
- }
-
- if(inPic) {
- if((inPut = rmalloc(MIP_MULT(inPic->width * inPic->height) + sizeof(struct mipmap), inName)))
- PasteMipMap((struct mipmap *)inPut->rawdata, inPic);
- pfree(inPic);
- }
- else
- eprintf("unknown fileformat %s\n", fileName);
-
- fclose(inFile);
- }
- else
- eprintf("cannot open %s\n", fileName);
-
- tfree(fileName);
- }
- }
-
- rewinddir(dirDir[j]);
- }
- }
-
- void PutInput(char *inName) {
- if(inPut) {
- mipBlock->dataofs[i] = mipFlow - (unsigned char *)mipBlock;
- mprintf(" - load texture %s\n", inPut->name);
-
- if ((bspMem->texdatasize + inPut->size) >= bspMem->max_texdatasize) {
- ExpandClusters(bspMem, LUMP_TEXTURES);
- mipBlock = (struct dmiptexlump_t *) bspMem->dtexdata;
- mipFlow = bspMem->dtexdata + bspMem->texdatasize;
- }
- bspMem->texdatasize += inPut->size;
- memcpy(mipFlow, inPut->rawdata, inPut->size);
- mipFlow += inPut->size;
- rfree(inPut);
- }
- else {
- mipBlock->dataofs[i] = -1;
- eprintf("texture %s not found!\n", inName);
- }
- }
-
- if (bspMem->maptexstrings[i][0] == '+') {
- int j;
- char name[20];
-
- strcpy(name, bspMem->maptexstrings[i]);
-
- for (j = 0; j < 20; j++) {
- if (j < 10)
- name[1] = '0' + j;
- else
- name[1] = 'A' + j - 10; // alternate animation
-
- GetInput(name);
- // see if this name exists in the wadfile
- if(inPut) {
- PutInput(name); // put only if it exists
- //FindMiptex(bspMem, name); // add to the miptex list, if somebody after us needs it
- }
- }
- }
- else {
- GetInput(bspMem->maptexstrings[i]);
- PutInput(bspMem->maptexstrings[i]);
- }
- }
-
- for(i = 0; i < wadAvail; i ++)
- fclose(wadFile[i]);
- for(i = 0; i < dirAvail; i ++)
- closedir(dirDir[i]);
- }
- else
- eprintf("cannot open wadfile(s) or dir(s)!\n");
- }
- }
-
- //===========================================================================
-
- /*
- * ==================
- * BeginBSPFile
- * ==================
- */
- void BeginBSPFile(__memBase)
- {
- bspMem->availHeaders = 0;
- AllocClusters(bspMem, (ALL_LUMPS | ALL_MAPS) & ~(LUMP_LIGHTING | LUMP_VISIBILITY));
-
- // edge 0 is not used, because 0 can't be negated
- bspMem->numedges = 1;
-
- // leaf 0 is common solid with no faces
- bspMem->numleafs = 1;
- bspMem->dleafs[0].contents = CONTENTS_SOLID;
-
- firstface = 0;
- }
-
- /*
- * ==================
- * FinishBSPFile
- * ==================
- */
- void FinishBSPFile(__memBase, FILE *bspFile)
- {
- mprintf("----- FinishBSPFile -----\n");
-
- WriteMiptex(bspMem);
- WriteBSP(bspFile, bspMem);
- PrintClusters(bspMem, 0, TRUE);
- }
-